-module(db_user).
-export([insert_user/7, get_user/1, get_users_by_language/3, get_number_users_by_language/1, update_user_last_login/1, delete_user/1, delete_all/0, add_homework_done/2, add_homework_given/2, add_times_listened/2, add_uploaded_audios/1]).
-include("records.hrl").


% Add a new user	
insert_user(Name, Pwd, Email, SpeakSpanish, SpeakSwedish, LearnSpanish, LearnSwedish) ->
	{_NegTime, Random} = get_time_and_random(),
	User = #user{
			last_login = {0, Random},
			name = Name,
			password = Pwd,
			email = Email,
			speak_spanish = SpeakSpanish,
			speak_swedish = SpeakSwedish,
			learn_spanish = LearnSpanish,
			learn_swedish = LearnSwedish,
			homework_given = 0,
			homework_done = 0,
			rating_homework = 0.0,
			uploaded_audios = 0,
			times_listened = 0,
			rating_audio = 0.0,
			level = 0.0},
	Fun = fun() ->
		mnesia:write(User)
	end,
	mnesia:transaction(Fun).
	

% Return a tuple {-time, random}
get_time_and_random() ->
	TupleTime = erlang:now(),
	Time = element(1,TupleTime)*1000000000000 + element(2,TupleTime)*1000000 + element(3,TupleTime),
	NegTime = Time * (-1),
	Random = random:uniform(Time),
	{NegTime, Random}.
		

% Update the last_login field when a user has just logged in
update_user_last_login(Name) ->
	{NegTime, Random} = get_time_and_random(),
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		UserNew = User#user{last_login = {NegTime, Random}},
		mnesia:delete_object(User),
		mnesia:write(UserNew)
	end,
	mnesia:transaction(Fun).
	
	
	
% Increments the amount of homework done
add_homework_done(Name, NewLevel) ->
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		NewUser = User#user{homework_done = User#user.homework_done + 1, level = NewLevel},
		mnesia:write(NewUser)
	end,
	mnesia:transaction(Fun).
	

% Increments the amount of homework given
add_homework_given(Name, NewRating) ->
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		NewUser = User#user{homework_given = User#user.homework_given + 1, rating_homework = NewRating},
		mnesia:write(NewUser)
	end,
	mnesia:transaction(Fun).
	
	
% Increments the amount of times listened
add_times_listened(Name, NewRating) ->
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		NewUser = User#user{times_listened = User#user.times_listened + 1, rating_audio = NewRating},
		mnesia:write(NewUser)
	end,
	mnesia:transaction(Fun).
	

% Increments the amount of uploaded audios
add_uploaded_audios(Name) ->
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		NewUser = User#user{uploaded_audios = User#user.uploaded_audios + 1},
		mnesia:write(NewUser)
	end,
	mnesia:transaction(Fun).


% Get user by name using the index
get_user(Name) ->
	Fun = fun() ->
		mnesia:index_read(user, Name, name)
	end,
	mnesia:transaction(Fun).


% Get a list of users [Offset, Offset+9] that are learning Language
get_users_by_language(Language, Offset, Number) -> 
	U = #user{
		last_login = '_',
		name = '_',
		password = '_',
		email = '_',
		speak_spanish = '_',
		speak_swedish = '_',
		learn_spanish = '_',
		learn_swedish = '_',
		homework_given = '_',
		homework_done = '_',
		rating_homework = '_',
		uploaded_audios = '_',
		times_listened = '_',
		rating_audio = '_',
		level = '_'
	},
	User = case Language of
		swedish ->
			U#user{learn_swedish = 1};
		spanish ->
			U#user{learn_spanish = 1}
	end,
	Fun = fun() ->
				Substract = Number - Offset,
				if 
					Offset > 17 ->
						{_, PreviousCont} = mnesia:select (user, [{User, [], ['$_']}], 9, read),
						AuxList = create_list( (Offset div 9)-1 , []),
						LastCont = lists:foldl(fun(_,Cont) -> {_,NextCont} = mnesia:select(Cont), NextCont end, PreviousCont, AuxList),
						if
							Substract < 9 ->
								Aux = element(6, LastCont),
								Aux2 = setelement(4, Aux, Substract),
								ModifiedCont = setelement(6, LastCont, Aux2),
								mnesia:select(ModifiedCont);
							true -> 
								mnesia:select(LastCont)
						end;
					Offset > 8 ->
						{_, PreviousCont} = mnesia:select (user, [{User, [], ['$_']}], 9, read),
						if
							Substract < 9 ->
								Aux = element(6, PreviousCont),
								Aux2 = setelement(4, Aux, Substract),
								ModifiedCont = setelement(6, PreviousCont, Aux2),
								mnesia:select(ModifiedCont);
							true -> 
								mnesia:select(PreviousCont)
						end;
					true ->
						if
							Substract < 9 ->
								mnesia:select (user, [{User, [], ['$_']}], Substract, read);
							true ->
								mnesia:select (user, [{User, [], ['$_']}], 9, read)
						end
				end
	end,

	{atomic, {Results, _}} = mnesia:transaction(Fun),
	Results.


create_list(0, L) -> L;
create_list(I, L) -> create_list(I-1, [I|L]).


% Get the amount of users that learn Language
get_number_users_by_language(Language) ->
	U = #user{
		last_login = '_',
		name = '_',
		password = '_',
		email = '_',
		speak_spanish = '_',
		speak_swedish = '_',
		learn_spanish = '_',
		learn_swedish = '_',
		homework_given = '_',
		homework_done = '_',
		rating_homework = '_',
		uploaded_audios = '_',
		times_listened = '_',
		rating_audio = '_',
		level = '_'
	},
	User = case Language of
		swedish ->
			U#user{learn_swedish = 1};
		spanish ->
			U#user{learn_spanish = 1}
	end,
	F = fun() -> mnesia:select (user, [{User, [], ['$_']}]) end,
	{atomic, Results} = mnesia:transaction(F),
	length(Results).


% Delete a user by name
delete_user(Name) ->
	Fun = fun() ->
		[User] = mnesia:index_read(user, Name, name),
		mnesia:delete_object(User)
	end,
	mnesia:transaction(Fun).
	

% Delete all rows
delete_all() ->
	Fun = fun() ->
		Res = mnesia:select(user, [{mnesia:table_info(user, wild_pattern), [], ['$_']}]),
		lists:map(fun(X) -> mnesia:delete_object(X) end, Res)
	end,
	mnesia:transaction(Fun).
